#ifndef GRAPHLOADER_HPP_INCLUDED
#define GRAPHLOADER_HPP_INCLUDED

#include "Graph.hpp"
#include "FrequentSubgraph.hpp"
#include <utility>
#include <string>
#include <map>
#include <boost/property_tree/ptree.hpp>

namespace TopologicalLearner
{
/** A class that loads graphs from XML-files.
 * This class provides an interface for loading graphs from XML-files.
 * It provides functions for loading a single graph from an XML-file or for specifying a whole
 * folder of XML-files. Internally, this class will keep track of all the semantic categories it discovers when
 * loading the files and assign to them a unique integer-valued ID.
*/
class GraphLoader
{

private:
    // FUNCTIONS:

    /**
    * Returns a (name,type) pair from the property tree.
    */
    std::pair<std::string,std::string> GetNameTypeAttr
        (const boost::property_tree::ptree::value_type v) const;

    /**
    * Returns the number of files in the specified directory (including subdirectories).
    */
    int CountFilesInDir(std::string sDir) const;

    /**
    * Loads the result from the gSpan algorithm and returns a vector of FrequentSubgraphs
    */
    std::vector<FrequentSubgraph> LoadGSpanData(std::string sFilename);

    /**
    * Saves a vector of graphs to file in the gSpan format
    */
    void SaveGSpanData(std::string sFilename, const std::vector<Graph>& kVec) const;

public:

    /// The mapping from the semantic category (string) to the unique integer-valued ID.
    std::map<std::string, int> m_TypesID;

    /// The mapping from the unique integer-valued ID to the semantic category (string).
    std::map<int, std::string> m_IDTypes;

    /// A set of all the types discovered thus far in the loading process.
    std::set<std::string> m_Types;

    /// An internal counter used for keeping track of the IDs.
    int m_iIDCounter;

    /// Keep track of the file names for each ID
    std::vector<std::string> m_GraphFilenames;


    /**
    * Loads a single graph from file and returns it.
    * @param sFilename The file name of the XML-file to load.
    *        rootNodeName is the tag name of the root node of the XML file.
    * @return A pair where the first component is a bool that describes the success of the operation and the second is the result
    * if the loading was successful.
    */
    std::pair<bool, Graph> LoadSingleGraph(std::string sFilename, bool bUnique = true , std::string rootNodeName = "MITquest");

    /**
    * Loads all the graphs in a specified directory.
    * @param sDir The directory to load from
    * @param iLimit The user can limit the maximum number of graphs to load (default is -1 which is no limit).
    * @param vResult A reference to a vector of graphs, which will be used to store the loaded graphs. Note that the function will erase any graphs
    * that are already stored in this vector.
    */
    int LoadAllGraphs(std::string sDir, std::vector<Graph>& vResult, int iLimit = -1, bool bUnique = true);




    GraphLoader() : m_iIDCounter(0) {}

    // We will allow GraphDatabase to access this object and vice-versa.
    friend class GraphDatabase;

};
}

#endif // GRAPHLOADER_HPP_INCLUDED
